package com.print.androidprintproject.page;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.print.androidprintproject.MainActivity;
import com.print.androidprintproject.R;
import com.print.androidprintproject.print.PrintJobService;
import com.print.printlib.export.MessageConst;
import com.print.printlib.export.errorCodes;

public class ConnectActivity extends BaseActivity
        implements OnClickListener, OnItemSelectedListener {
    private LinearLayout header;
    private Spinner spinner_printer_type;
    private Spinner spinner_interface_type;
    private ArrayAdapter<CharSequence> arr_adapter;
    private ArrayAdapter<CharSequence> printType_adapter;
    private final static int SCANNIN_GREQUEST_CODE = 2;
    public static final int CONNECT_DEVICE = 1;
    public static final int ENABLE_BT = 3;
    // 不同蓝牙链接方式的判断依据 “确认连接”
    public static int connectMains = 0;
    protected static final String TAG = "ConnectActivity";
    private static Button btn_conn_devices, btn_print_test, btn_status_test;
    public static boolean isConnected = false;// 蓝牙连接状态
    public static String devicesName = "未知设备";
    private static String devicesAddress;
    public static Boolean paired = false;
    private static BluetoothDevice mDevice;
    private static UsbDevice mUSBDevice;
    private Context mContext;
    private int interfaceType = 0;
    private IntentFilter btDisconReceiver;
    private List<UsbDevice> deviceList;
    private static final String ACTION_USB_PERMISSION = "com.android.usb.USB_PERMISSION";
    private BluetoothAdapter mBtAdapter;
    private TextView tv_device_name, tv_printer_address;
    private static boolean hasRegDisconnectReceiver = false;
    private ProgressDialog dialogH;

    private PrintJobService printJobService;

    private Object printPortObject;
    /**
     * 显示扫描结果
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_connect);
        printJobService = PrintJobService.getObject(this, mHandler);
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
        initWnd();
    }

    // 用于接受连接状态消息的 Handler
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MessageConst.MSG_OPEN:
                    Bundle bundle = msg.getData();
                    Integer code = bundle.getInt("code");
                    isConnected = code == 1 ? true : false;
                    Log.d(MainActivity.TAG, "Connect result is:" + isConnected);
                    if (interfaceType == 0) {
                        btDisconReceiver = new IntentFilter();
                        btDisconReceiver.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
                        mContext.registerReceiver(btDisconnectReceiver, btDisconReceiver);
                        hasRegDisconnectReceiver = true;
                        mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(devicesAddress);
                    }
                    updateButtonState(isConnected);
                    if (isConnected)
                        Toast.makeText(mContext, getString(R.string.connect_success), Toast.LENGTH_SHORT).show();
                    else
                        Toast.makeText(mContext, getString(R.string.no_connected), Toast.LENGTH_SHORT).show();
                    break;
                case MessageConst.MSG_CLOSE:
                    isConnected = false;
                    if (interfaceType == 0 && hasRegDisconnectReceiver) {
                        mContext.unregisterReceiver(btDisconnectReceiver);
                        hasRegDisconnectReceiver = false;
                    }
                    break;
            }
        }
    };

    /**
     * 初始化界面
     */
    private void initWnd() {
        mContext = ConnectActivity.this;
        header = findViewById(R.id.ll_headerview_settingactivity);
        // 初始化标题
        initHeader(header);
        // 初始化下拉列表框
        spinner_interface_type = findViewById(R.id.spinner_interface_type);
        // 初始化按钮的点击事件
        btn_conn_devices = findViewById(R.id.btn_conn_devices);
        btn_print_test = findViewById(R.id.btn_print_test);
        btn_status_test = findViewById(R.id.btn_status_test);
        // 设置按钮的监听事件
        btn_conn_devices.setOnClickListener(this);
        btn_print_test.setOnClickListener(this);
        btn_status_test.setOnClickListener(this);

        // 展示设备名和设备地址
        tv_device_name = findViewById(R.id.tv_device_name);
        tv_printer_address = findViewById(R.id.tv_printer_address);
        // // 适配器
        ArrayList<String> prints = printJobService.getSupportPrinters();
        String[] listPrinters = new String[prints.size()];
        printJobService.getSupportPrinters().toArray(listPrinters);
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, listPrinters);

        spinner_printer_type = findViewById(R.id.spinner_printer_type);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner_printer_type.setAdapter(adapter);
        printType_adapter = ArrayAdapter.createFromResource(this, R.array.interface_type,
                android.R.layout.simple_spinner_item);

        // // 设置样式
        printType_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // 加载适配器
        spinner_interface_type.setAdapter(printType_adapter);
        // 下拉列表框的监听事件
        spinner_interface_type.setOnItemSelectedListener(this);

        updateButtonState(isConnected);
        // 初始化进度条对话框
        dialogH = new ProgressDialog(this);
        dialogH.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialogH.setCancelable(false);
        dialogH.setCanceledOnTouchOutside(false);
    }

    /**
     * 初始化标题上的信息
     */
    private void initHeader(LinearLayout header) {
        setHeaderLeftText(header, getString(R.string.back), new OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        headerConnecedState.setText(getTitleState());
        setHeaderLeftImage(header, new OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        setHeaderCenterText(header, getString(R.string.headview_setting));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    /**
     * 发起连接/关闭请求
     */
    private void connectDevice() {
        if (printJobService.getConnect()) {
            printJobService.close();
            isConnected = false;
            updateButtonState(false);
        } else {
            setTitleState(mContext.getResources().getString(R.string.connecting));
            headerConnecedState.setText(R.string.connecting);
            Intent intent = null;
            if (interfaceType == 0)
                intent = new Intent(mContext, DeviceListBluetooth.class);
            else if(interfaceType == 1)
                intent = new Intent(mContext, DeviceListUsb.class);
            else if(interfaceType == 2) {
                intent = new Intent(mContext, IpEditActivity.class);
                intent.putExtra("WIFI_NAME", getWiFiName());
                intent.putExtra("WIFI_ADDR", getIpAddr());
            } else {
//                printPortObject = "/dev/ttyS1:9600:0:0";
//                new connectThread().start();
                intent = new Intent(mContext, SerialDeviceList.class);
            }
            if(intent != null)
                startActivityForResult(intent, CONNECT_DEVICE);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_conn_devices:
                connectDevice();
                break;
            case R.id.btn_print_test:
                if (isConnected) {
                    new Thread(new Runnable() {
                        public void run() {
                            printJobService.printNormal();
                        }
                    }).start();
                }
                break;
            case R.id.btn_status_test:
                if (isConnected) {
                    errorCodes error = printJobService.getStatus();
                    Log.d(TAG, error.toString());
                    Toast.makeText(mContext, error.toString(), Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(mContext, getString(R.string.no_connected), Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != Activity.RESULT_OK)
            return;
        if (requestCode == CONNECT_DEVICE) {// 连接设备
            if (interfaceType == 0) {
                devicesAddress = data.getExtras().getString(DeviceListBluetooth.EXTRA_DEVICE_ADDRESS);
                devicesName = data.getExtras().getString(DeviceListBluetooth.EXTRA_DEVICE_NAME);
                paired = data.getExtras().getBoolean(DeviceListBluetooth.EXTRA_PAIRED);
                connect2Bluetooth();
            } else if (interfaceType == 1) {
                mUSBDevice = data.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                UsbManager mUsbManager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
                if (!mUsbManager.hasPermission(mUSBDevice)) {
                    PendingIntent pendingIntent = PendingIntent.getBroadcast(ConnectActivity.this, 0, new Intent(ACTION_USB_PERMISSION), 0);
                    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
                    filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
                    filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
                    ConnectActivity.this.registerReceiver(mUsbReceiver, filter);
                    mUsbManager.requestPermission(mUSBDevice, pendingIntent); // 该代码执行后，系统弹出一个对话框
                } else {
                    printPortObject = mUSBDevice;
                    new connectThread().start();
                }
            } else if (interfaceType == 2) {
                devicesName = "Net device";
                devicesAddress = data.getStringExtra("ip_address");
                printPortObject = devicesAddress + ":9100";
                new connectThread().start();
            } else {
                //Serial
                String path = data.getStringExtra("path");
                String baudrate = data.getStringExtra("baudrate");
                printPortObject = path + ":" + baudrate + ":0:0";
                new connectThread().start();
            }
        }
    }

    private void connect2Bluetooth() {
        if (paired) {
            printPortObject = devicesAddress;
            new connectThread().start();
        } else {
            IntentFilter boundFilter = new IntentFilter();
            boundFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
            mContext.registerReceiver(boundDeviceReceiver, boundFilter);
            try {
                // 开始配对 这段代码打开输入配对密码的对话框
                Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
                mDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(devicesAddress);
                createBondMethod.invoke(mDevice);
            } catch (Exception e) {
                Toast.makeText(ConnectActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                Log.e(TAG, "make pair error", e);
            }
        }
    }

    private void updateButtonState(boolean isConnected) {
        if (isConnected) {
            btn_conn_devices.setText(R.string.disconnect);
            setTitleState(mContext.getResources().getString(R.string.on_line));
            headerConnecedState.setText(R.string.on_line);
            tv_device_name.setText(getString(R.string.printerName).split(":")[0] + ": " + devicesName);
            tv_printer_address.setText(getString(R.string.printerAddress).split(":")[0] + ": " + devicesAddress);
        } else {
            tv_device_name.setText(getString(R.string.printerName));
            tv_printer_address.setText(getString(R.string.printerAddress));
            btn_conn_devices.setText(R.string.connect);
            headerConnecedState.setText(R.string.off_line);
            setTitleState(mContext.getResources().getString(R.string.off_line));
        }
    }

    private BroadcastReceiver boundDeviceReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (!mDevice.equals(device)) {
                    return;
                }
                switch (device.getBondState()) {
                    case BluetoothDevice.BOND_BONDING:
                        Log.i(TAG, "bounding......");
                        break;
                    case BluetoothDevice.BOND_BONDED:
                        Log.i(TAG, "bound success");
                        // if bound success, auto initWnd BluetoothPrinter. open
                        // connect.
                        mContext.unregisterReceiver(boundDeviceReceiver);
                        printPortObject = devicesAddress;
                        new connectThread().start();
                        break;
                    case BluetoothDevice.BOND_NONE:
                        Log.i(TAG, "执行顺序----4");

                        mContext.unregisterReceiver(boundDeviceReceiver);
                        Log.i(TAG, "bound cancel");
                        break;
                    default:
                        break;
                }
            }
        }
    };

    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
        @SuppressLint("NewApi")
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.w(TAG, "receiver action: " + action);

            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    mContext.unregisterReceiver(mUsbReceiver);
                    UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)
                            && mUSBDevice.equals(device)) {
                        printPortObject = mUSBDevice;
                        new connectThread().start();
                    } else {
                        Log.e(TAG, "permission denied for device " + device);
                    }
                }
            }
        }
    };


    private class connectThread extends Thread {
        @Override
        public void run() {
            String printName = spinner_printer_type.getSelectedItem().toString();
            printJobService.doInvoke(PrintJobService.COMMAND_TYPE.CMD_OPEN, printName, printPortObject);
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        if (parent == spinner_interface_type) {
            interfaceType = position;
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) {

    }

    public BroadcastReceiver btDisconnectReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
                if (device != null && isConnected && device.equals(mDevice)) {
                    printJobService.doInvoke(PrintJobService.COMMAND_TYPE.CMD_CLOSE);
                }
            }
        }
    };

    private String getWiFiName() {
        String wifiName = null;
        WifiManager mWifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (!mWifi.isWifiEnabled()) {
            mWifi.setWifiEnabled(true);
        }
        WifiInfo wifiInfo = mWifi.getConnectionInfo();
        wifiName = wifiInfo.getSSID();
        wifiInfo.getIpAddress();
        Log.i("yxz", "wifiName" + wifiName);
        wifiName = wifiName.replaceAll("\"", "");
        return wifiName;

    }

    private String getIpAddr()  {
        WifiManager mWifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (!mWifi.isWifiEnabled()) {
            mWifi.setWifiEnabled(true);
        }
        WifiInfo wifiInfo = mWifi.getConnectionInfo();
        int i = wifiInfo.getIpAddress();
        return (i&0xFF) +"."+ ((i >> 8) & 0xFF) +"."+ ((i >> 16) & 0xFF) +"."+ ((i >> 24) & 0xFF);
    }
}
